home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / OpenDocSetup / BetterFindFolder.cpp next >
Encoding:
C/C++ Source or Header  |  1997-02-13  |  6.0 KB  |  271 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        BetterFindFolder.cpp
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Owned by:    Nick Pilch
  7.  
  8.     Copyright:    © 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <2>     6/23/96    NP        10002: Launch time speedups.
  13.          <1>     6/21/96    NP        first checked in
  14.  
  15.     To Do:
  16. */
  17.  
  18. /*
  19. **    (C) Copyright 1995-1996 Damon Cokenias All Rights Reserved
  20. **    Permission is granted to use and distribute this source code freely so long
  21. **    as this copyright notice is not changed.
  22. */
  23.  
  24. #ifndef BETTERFINDFOLDER_H
  25. #include "BetterFindFolder.h"
  26. #endif
  27.  
  28. #ifndef __FOLDERS__
  29. #include <Folders.h>
  30. #endif
  31.  
  32. #ifndef __LOWMEM__
  33. #include <LowMem.h>
  34. #endif
  35.  
  36. #ifndef __FINDER__
  37. #include <Finder.h>
  38. #endif
  39.  
  40. #ifndef __ERRORS__
  41. #include <Errors.h>
  42. #endif
  43.  
  44. #if PRAGMA_ALIGN_SUPPORTED
  45. #pragma options align=mac68k
  46. #endif
  47.  
  48. typedef struct {
  49.     OSType                parentFolderType;    // parent folder (ie. kPreferencesFolderType)
  50.     Str32                folderName;            // name of folder
  51.     Boolean                onSystemDisk;        // true means folder is on system disk
  52.     short                iconID;                // 0 means no icon
  53. } BetterFolderRec, **BetterFolderHandle;
  54.  
  55. #define                    kFolderResType        'BFld'
  56. #define                    kMagicIconFileName    "\pIcon\015"
  57.  
  58. #if PRAGMA_ALIGN_SUPPORTED
  59. #pragma options align=reset
  60. #endif
  61.  
  62. static
  63. OSErr    FindApplicationFolder (short* vRefNum, long* dirID)
  64. {
  65.     static Boolean        doneIt = false;
  66.     static short        cachedVRefNum;
  67.     static long            cachedDirID;
  68.     
  69.     if (doneIt) {
  70.         *vRefNum = cachedVRefNum;
  71.         *dirID = cachedDirID;
  72.         return noErr;
  73.     }
  74.     
  75.     FCBPBRec            pb;
  76.     
  77.     pb.ioNamePtr = nil;
  78.     pb.ioRefNum = LMGetCurApRefNum ();
  79.     pb.ioFCBIndx = 0;
  80.     
  81.     OSErr                error = PBGetFCBInfoSync (&pb);
  82.     if (error)
  83.         return error;
  84.     
  85.     doneIt = true;
  86.     *vRefNum = cachedVRefNum = pb.ioFCBVRefNum;
  87.     *dirID = cachedDirID = pb.ioFCBParID;
  88.     
  89.     return noErr;
  90. }
  91.  
  92. static
  93. OSErr    CreateCustomFolderIcon (short vRefNum, long dirID, short iconID)
  94. {
  95.     static OSType    resourceTypes [6] = { 'ICN#', 'icl8', 'icl4', 'ics#', 'ics8', 'ics4' };
  96.     OSErr            error;
  97.     
  98.     /* create the icon file and make it invisible */
  99.     error = HCreate (vRefNum, dirID, kMagicIconFileName, 0, 0);
  100.     if (error)
  101.         return error;
  102.     
  103.     HCreateResFile (vRefNum, dirID, kMagicIconFileName);
  104.     
  105.     CInfoPBRec    pb;
  106.     
  107.     pb.hFileInfo.ioNamePtr = kMagicIconFileName;
  108.     pb.hFileInfo.ioVRefNum = vRefNum;
  109.     pb.hFileInfo.ioFDirIndex = 0;
  110.     pb.hFileInfo.ioDirID = dirID;
  111.     
  112.     error = PBGetCatInfoSync (&pb);
  113.     if (error)
  114.         return error;
  115.     
  116.     pb.hFileInfo.ioFlFndrInfo.fdFlags |= kIsInvisible;
  117.     pb.hFileInfo.ioDirID = dirID;
  118.     error = PBSetCatInfoSync (&pb);
  119.     if (error)
  120.         return error;
  121.     
  122.     /* copy the icon resources into the icon file */
  123.     short        oldResFile = CurResFile ();
  124.     short        iconResFile = HOpenResFile (vRefNum, dirID, kMagicIconFileName, fsRdWrPerm);
  125.     if (iconResFile == -1)
  126.         return ResError ();
  127.     
  128.     Boolean        foundAtLeastOne = false;
  129.     
  130.     for (int i = 0; (i < 6) && (error == noErr); ++i) {
  131.         UseResFile (oldResFile);
  132.         Handle        iconHandle = GetResource (resourceTypes [i], iconID);
  133.         if (iconHandle) {
  134.             foundAtLeastOne = true;
  135.             DetachResource (iconHandle);
  136.             UseResFile (iconResFile);
  137.             AddResource (iconHandle, resourceTypes [i], kCustomIconResource, "\p");
  138.             error = ResError ();
  139.         }
  140.     }
  141.     
  142.     CloseResFile (iconResFile);
  143.     UseResFile (oldResFile);
  144.     
  145.     if (error)
  146.         return error;
  147.  
  148.     if (foundAtLeastOne == false)
  149.         return resNotFound;
  150.     
  151.     /* finally, set the custom icon bit of the folder */
  152.     Str63                folderName;
  153.     
  154.     pb.hFileInfo.ioNamePtr = folderName;
  155.     pb.hFileInfo.ioVRefNum = vRefNum;
  156.     pb.hFileInfo.ioFDirIndex = -1;
  157.     pb.hFileInfo.ioDirID = dirID;
  158.     
  159.     error = PBGetCatInfoSync (&pb);
  160.     if (error)
  161.         return error;
  162.     
  163.     pb.hFileInfo.ioFlFndrInfo.fdFlags |= kHasCustomIcon;
  164.     
  165.     pb.hFileInfo.ioNamePtr = nil;
  166.     pb.hFileInfo.ioDirID = dirID;
  167.  
  168.     error = PBSetCatInfoSync (&pb);
  169.  
  170.     return error;
  171. }
  172.  
  173. static
  174. OSErr    CreateLocalFolder (short vRefNum, long dirID, BetterFolderRec* folderRecord,
  175.             long* newDirID)
  176. {
  177.     HParamBlockRec    pb;
  178.     
  179.     pb.ioParam.ioNamePtr = folderRecord -> folderName;
  180.     pb.ioParam.ioVRefNum = vRefNum;
  181.     pb.fileParam.ioDirID = dirID;
  182.     
  183.     OSErr            error = PBDirCreateSync (&pb);
  184.     if (error)
  185.         return error;
  186.     
  187.     *newDirID = pb.fileParam.ioDirID;
  188.     if (folderRecord -> iconID != 0)
  189.         return CreateCustomFolderIcon (vRefNum, *newDirID, folderRecord -> iconID);
  190.     else
  191.         return noErr;
  192. }
  193.  
  194. static
  195. OSErr    FindLocalFolder (short vRefNum, long dirID, Boolean createFolder,
  196.             BetterFolderRec* folderRecord, long* foundDirID)
  197. {    
  198.     CInfoPBRec        pb;
  199.     
  200.     pb.hFileInfo.ioNamePtr = folderRecord -> folderName;
  201.     pb.hFileInfo.ioVRefNum = vRefNum;
  202.     pb.hFileInfo.ioFDirIndex = 0;
  203.     pb.hFileInfo.ioDirID = dirID;
  204.     
  205.     OSErr    error = PBGetCatInfoSync (&pb);
  206.     if ((error == fnfErr) && createFolder)
  207.         return CreateLocalFolder (vRefNum, dirID, folderRecord, foundDirID);
  208.     else {
  209.         *foundDirID = pb.hFileInfo.ioDirID;
  210.         return error;
  211.     }    
  212. }
  213.  
  214. static
  215. OSErr    GetFolderRecord (OSType key, BetterFolderRec* folderRecord)
  216. {
  217.     // Make a pascal string of key.  Make sure the OSType is copied to an even address
  218.     // for 68000 compatability.  This means the length byte is actually at index 1, not 0
  219.     unsigned char    keyString [6];
  220.     *((OSType*) &keyString [2]) = key;
  221.     keyString [1] = 4;
  222.     
  223.     Handle        res = GetNamedResource (kFolderResType, &keyString [1]);
  224.     if (!res) {
  225.         OSErr        error = ResError ();
  226.         return error ? error : resNotFound;
  227.     }
  228.     
  229.     *folderRecord = **(BetterFolderHandle) res;
  230.     return noErr;
  231. }
  232.  
  233. pascal
  234. OSErr    BetterFindFolder (short vRefNum, OSType folderType, Boolean createFolder,
  235.             short* foundVRefNum, long* foundDirID)
  236.  
  237. {
  238.     OSErr        error;
  239.     
  240.     if (folderType == kAppFolderType) {
  241.         return FindApplicationFolder (foundVRefNum, foundDirID);        
  242.     } else {
  243.         error = FindFolder (vRefNum, folderType, createFolder, foundVRefNum, foundDirID);
  244.         if (error == fnfErr) {
  245.             
  246.             BetterFolderRec            folderRecord;
  247.         
  248.             error = GetFolderRecord (folderType, &folderRecord);
  249.             if (error)
  250.                 return error;
  251.                         
  252.             error = BetterFindFolder (folderRecord.onSystemDisk ? kOnSystemDisk : vRefNum,
  253.                     folderRecord.parentFolderType, createFolder, foundVRefNum, foundDirID);
  254.             if (error)
  255.                 return error;
  256.  
  257.             return FindLocalFolder (*foundVRefNum, *foundDirID, createFolder, &folderRecord,
  258.                     foundDirID);
  259.         } else
  260.             return error;
  261.     }
  262. }
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.